package com.gao.api.gate.quick.proto.http;

import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.DefaultLastHttpContent;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.LastHttpContent;

import java.util.ArrayList;
import java.util.List;

/**
 * <p></p>
 *
 * @author gaoshuangwen
 * @since 2022/01/06 11:58
 */
public class HttpBody {

    private boolean loadedCompletely;
    // context-length
    private int contentLength;
    private List<HttpContent> chunks;

    public HttpBody(int contentLength) {
        this.contentLength = contentLength;
    }
    public HttpBody() {

    }

    public boolean loading(HttpContent content) {
        if (chunks == null) {
            chunks = new ArrayList<>();
        }
        if (content instanceof LastHttpContent) {
            loadedCompletely = true;
            return true;
        }
        chunks.add(content);
        return false;
    }

    public byte[] bodyToBytes() {
        if (chunks == null||chunks.size() == 0 ) {
            return null;
        }

        int size = 0;
        for (HttpContent chunk : chunks) {
            size += chunk.content().readableBytes();
        }
        final byte[] body = new byte[size];
        int offset = 0;
        for (HttpContent chunk : chunks) {
            final ByteBuf content = chunk.content();
           // content.release();
            final int len = content.readableBytes();
            content.readBytes(body);
            //content.getBytes(content.readerIndex(), body, offset, len);
            offset += len;
        }
        return body;
    }
    public boolean finishBufferedBodyIfIncomplete() {
        if (! loadedCompletely) {
            loading(new DefaultLastHttpContent());
            return true;
        }
        return false;
    }
    public void disposeBufferedBody() {
        chunks.forEach(chunk -> {
            if ((chunk != null) && (chunk.refCnt() > 0)) {
                chunk.release();
            }
        });
        chunks.clear();
    }
    public boolean isLoadedCompletely() {
        return loadedCompletely;
    }

    public int getContentLength() {
        return contentLength;
    }

    public List<HttpContent> getChunks() {
        return chunks;
    }
    public boolean hasBody() {
        return chunks != null && chunks.size()>0;
    }
}
